package checkonline

import (
	"MqttCloudProtocolServer/ProtocolServer/mqttlib"
	"encoding/json"
	"sync"
	"time"

	"MqttCloudProtocolServer/publiclib/datamodel/redismodel"
	"MqttCloudProtocolServer/publiclib/datastorage"

	"github.com/wonderivan/logger"
)

type MQTTReportData struct {
	SleepTime int    `json:"sleep_time"`
	TryTimes  int    `json:"try_times"`
	Time      string `json:"time"`
}
type MQTTReportInformation struct {
	Projectname    string          `json:"projectname"`
	Projectversion string          `json:"projectversion"`
	Fwversion      string          `json:"fwversion"`
	Cfgversion     string          `json:"cfgversion"`
	Writepoint     []string        `json:"writepoint"`
	Response       *MQTTReportData `json:"response"`
}

//TCPServer TCP收发服务器
type CheckOnlineAnalysis struct {
	mqttlib.OperatorBase
	mqttSender func(key string, buffer []uint8)
	sleep_time int
	try_times  int
	last_time  time.Time
	locker     sync.Mutex
	name       string
}

//这里的callback是MQTT的发送函数
//这是另一个外部线程控制的
func (_this *CheckOnlineAnalysis) SetReceive(callback func(key string, buffer []uint8)) {
	_this.mqttSender = callback
}

//Start Fun
func (_this *CheckOnlineAnalysis) Start() bool {
	t := time.Now()
	datastorage.GetRedisStorageContent().SaveToRedis("realData", &redismodel.RealData{
		Key:      _this.name,
		Value:    0,
		ValueDis: "Off",
		LastTime: t,
	})
	_this.last_time = time.Now()
	return true
}
func (_this *CheckOnlineAnalysis) SetName(name string) {
	_this.name = name + "-0-Online"
}

//Modify Fun
func (_this *CheckOnlineAnalysis) Modify(params interface{}) bool {
	return true
}

//Close Fun
func (_this *CheckOnlineAnalysis) Close() bool {
	return true
}

//SendData Fun
func (_this *CheckOnlineAnalysis) SendData(buffer []uint8) bool {
	logger.Trace(string(buffer))
	res := new(MQTTReportInformation)
	if err := json.Unmarshal(buffer, res); err != nil {
		logger.Alert("上报报文错误-" + err.Error())
	} else {
		data := res.Response
		t, err := time.Parse("", data.Time)
		if err != nil {
			t = time.Now()
		}
		_this.sleep_time = data.SleepTime
		_this.try_times = data.TryTimes
		datastorage.GetRedisStorageContent().SaveToRedis("realData", &redismodel.RealData{
			Key:      _this.name,
			Value:    1,
			ValueDis: "On",
			LastTime: t,
		})
		_this.locker.Lock()
		_this.last_time = time.Now()
		_this.locker.Unlock()
		timer := time.NewTimer(time.Duration(_this.sleep_time*data.TryTimes) * time.Second)
		timeout := func() {
			<-timer.C
			currentTime := time.Now()
			span := currentTime.Sub(_this.last_time)
			if span.Seconds() >= float64(_this.sleep_time*data.TryTimes) {
				_this.locker.Lock()
				datastorage.GetRedisStorageContent().SaveToRedis("realData", &redismodel.RealData{
					Key:      _this.name,
					Value:    0,
					ValueDis: "Off",
					LastTime: currentTime,
				})
				_this.last_time = time.Now()
				_this.locker.Unlock()
			}
		}
		go timeout()

	}
	return true
}

//Delete Fun
func (_this *CheckOnlineAnalysis) Delete() bool { return true }
